package cdu.sl.filter;

import cdu.sl.custom.CustomUserDetails;
import cdu.sl.pojo.entity.manage.User;
import cdu.sl.repository.manage.UserRepository;
import cdu.sl.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.util.Optional;

@Slf4j
@Component
@RequiredArgsConstructor
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    private static final String BEARER_PREFIX = "Bearer ";

    private final UserRepository userRepository;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {


        String requestURI=request.getRequestURI();
        log.info("校验token...");
        // 从请求头中获取认证信息
        String token = extractToken(request);
        if (token == null || token.isEmpty()) {
            log.info("请求头中没有Authorization信息");
            filterChain.doFilter(request, response);
            return;
        }
        if(requestURI.contains("/login")||requestURI.contains("/add")){
            log.info("登录请求,放行");
            filterChain.doFilter(request,response);
            return;
        }

        Long userId = null;
        // 如果token不为空 , 需要对其进行校验
        try {
            Claims claims = JwtUtils.parseToken(token);
            userId = claims.get("userId", Long.class);
        } catch (Exception e) {
            log.error("token校验异常：{}", e.getMessage());
            throw new RuntimeException("token校验不通过");
        }

        Optional<User> opt = userRepository.findById(userId);
        if (opt.isPresent()) {
            log.info("用户详情：{}",opt.get());
            CustomUserDetails loginUser = new CustomUserDetails(opt.get());
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }

        log.info("校验token通过,用户信息已保存到SecurityContext");

        filterChain.doFilter(request, response);
    }


    private String extractToken(HttpServletRequest request) {
        String header = request.getHeader("Authorization");
        if (header != null && header.startsWith(BEARER_PREFIX)) {
            return header.substring(BEARER_PREFIX.length());
        }
        log.info("token:{}没有以Bearer 开头 ,不是jwt认证头",request.getHeader("Authorization"));
        return null;
    }


}
